#include <iostream>
#include <iomanip>
#include "EquationSolver.h"

using namespace std;

double D = 55; //无伤大雅，再定义一个f就不用全局变量

double f(double x){
    double l = 89;
    double beta1 = 11.5 / 180 * M_PI;   //弧度制
    double h = 49;
    double A = l * sin(beta1);
    double B = l * cos(beta1);
    double C = (h + 0.5 * D) * sin(beta1) - 0.5 * D * tan(beta1);
    double E = (h + 0.5 * D) * cos(beta1) - 0.5 * D;
    return A * sin(x) * cos(x) + B * sin(x) * sin(x) - C * cos(x) - E * sin(x);
}

double df(double x){
    double l = 89;
    double beta1 = 11.5 / 180 * M_PI;   //弧度制
    double h = 49;
    double A = l * sin(beta1);
    double B = l * cos(beta1);
    double C = (h + 0.5 * D) * sin(beta1) - 0.5 * D * tan(beta1);
    double E = (h + 0.5 * D) * cos(beta1) - 0.5 * D;
    return A * cos(2*x) + B * sin(2*x) + C * sin(x) - E * cos(x);
}

int main()
{
    typedef double (*fp)(double);
    fp fpi = f;
    fp dfpi = df;
    MyFunc f(fpi,dfpi);
    cout << "Question F: " << endl;
    double err = std::numeric_limits<double>::epsilon();

    cout << "(a) Choose x0 = pi/4" << endl;
    D = 55;
    Newton N(M_PI/4.0,err,100,f);
    double alpha = N.solve();
    cout << "The Newton result of alpha is " << setiosflags(ios::fixed) << setprecision(2) << alpha << endl;
    cout << "Change unit: alpha = " << setiosflags(ios::fixed) << setprecision(2) << alpha * 180 / M_PI << " degree" << endl;
    cout << endl;

    cout << "(b) Choose x0 = 33 degree" << endl;
    D = 30;
    Newton N2(33.0 / 180.0 * M_PI,err,100,f);
    cout << "The Newton result of alpha is " << setiosflags(ios::fixed) << setprecision(2) << N2.solve() * 180 / M_PI << " degree" << endl;
    cout << endl;

    cout << "(c) Choose x1 = 33 degree, x0 = 75 degree " << endl;
    Secant S(75.0 / 180.0 * M_PI,33.0 / 180.0 * M_PI,err,err,100,f);
    cout << "The Secant result of alpha is " << setiosflags(ios::fixed) << setprecision(2) << S.solve() * 180 / M_PI << " degree" << endl;
    cout << "Choose x1 = 33 degree, x0 = -327 degree " << endl;
    Secant S2(-327.0 / 180.0 * M_PI,33.0 / 180.0 * M_PI,err,err,100,f);
    cout << "The Secant result of alpha is " << setiosflags(ios::fixed) << setprecision(2) << S2.solve() * 180 / M_PI << " degree" << endl;

    return 0;
}